﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.DirectoryServices;
using NLog;
using System.Drawing;
using System.Security.Cryptography; //SHA256Managed -> Hashberechnung
using Oracle.DataAccess.Types;
using System.Collections;
using System.Collections.Generic;

namespace PhotoADSync
{
    class Vergleich
    {

        private static Logger myLogger = LogManager.GetCurrentClassLogger();
        private ImageConverter converter = new ImageConverter();
        //Bitmap ADvergleich;
        MemoryStream s;

        /// <summary>
        /// Konstruktor
        /// </summary>
        public Vergleich()
        {

        }

        /// <summary>
        /// Wenn kein Foto vorhanden -> Setzen des neuen Thumbnails
        /// Bei Erfolgreichen Vergleich -> Setzen des neuen Thumbnails
        /// </summary>
        public void Set(ArrayList list)
        { 
            try
            {
                for (int i = 0; i < 2; )
                {
                    myLogger.Info(i+1 + ". Durchlauf in: " + Properties.Settings.Default.LDAParray[i]);

                    foreach (Logo pic in list)
                    {

                        DirectoryEntry entry = new DirectoryEntry(Properties.Settings.Default.LDAParray[i]);
                        DirectorySearcher mySearcher = new DirectorySearcher(entry);
                        mySearcher.Filter = "(&(objectClass=User)(mail=" + pic.Mailadresse + "))";

                        foreach (SearchResult res in mySearcher.FindAll())
                        {
                            DirectoryEntry de = res.GetDirectoryEntry();
                            //de.Username = "ax01141";
                            //de.Password = "adtest123!";
                            
                            // Image to Bitmap Convert 
                            ImageConverter ic = new ImageConverter();
                            byte[] Thumb = MakeThumbnail(pic.DBLogo.Value);
                            Image img = (Image)ic.ConvertFrom(Thumb);
                            Bitmap DBvergleich = new Bitmap(img);

                            // Bitmap to Bytearray[] für den Insert
                            Byte[] Imagebyte = new Byte[1];
                            Imagebyte = (Byte[])converter.ConvertTo(DBvergleich, Imagebyte.GetType());
                            
                            if(de.Properties.Contains("thumbnailPhoto"))
                            {
                                s = new MemoryStream(de.Properties["thumbnailPhoto"][0] as byte[]);
                                Bitmap ADvergleich = (Bitmap)Bitmap.FromStream(s);                

                                   if (AreBitmapEqual(ADvergleich, DBvergleich) == false)
                                   {
                                       try
                                       {
                                           InsertAD(de, Thumb);
                                       }
                                       catch (Exception e)
                                       {
                                           myLogger.Info(pic.Mailadresse + ": Zugriff auf User nicht möglich.", e);
                                           break;
                                       }
                           
                                       myLogger.Info(pic.Mailadresse + ": Foto wurde erfolgreich ersetzt.");
                                   }
                                   else
                                   {
                                       myLogger.Info(pic.Mailadresse + ": Foto bereits vorhanden.");
                                   }
                            }
                            else
                            {
                                InsertAD(de, Thumb);
                                myLogger.Info(pic.Mailadresse + ": Foto wurde erfolgreich gespeichert.");
                            }
                            
                        }
                    }
                    i++;
                }
                }
                catch (Exception ex)
                {
                    myLogger.FatalException("Suche der User mit hinterlegter E-Mail nicht möglich.", ex);
                }
            }

        /// <summary>
        /// Aus ByteArray Thumbnailimage erstellen und zurückgeben
        /// </summary>
        /// <returns>MemoryStream-Array</returns>
        public static byte[] MakeThumbnail(byte[] Imagebytearray)
        {
            MemoryStream memstream = new MemoryStream();
            Image _image = Image.FromStream(new MemoryStream(Imagebytearray));
            double factorone = (double)7/10;
            double factortwo = (double)5/10;

            double width = _image.Width;
            double height = _image.Height;
            int newwidth = (int)(width * factorone);
            int newheight = (int)(height * factorone);

            if (newwidth > 1000 || newheight > 1000)
            {
                newwidth = newwidth / 10;
                newheight = newheight / 10;
            }

            if (newwidth > 200 || newheight > 200) 
            {
                newwidth = (int)(width * factortwo);
                newheight = (int)(height * factortwo);
            }



            using (Image thumbnail = _image.GetThumbnailImage(newwidth, newheight, null, new IntPtr()))
            {
                thumbnail.Save(memstream, System.Drawing.Imaging.ImageFormat.Png);
                return memstream.ToArray();
            }
        }


        /// <summary>
        /// 1. Löschen des alten Fotos 
        /// 2. Insert des neuen Fotos
        /// 3. Commit
        /// </summary>
        private void InsertAD(DirectoryEntry de, byte[] thumb) 
        {
            de.Properties["thumbnailPhoto"].Clear();
            de.Properties["thumbnailPhoto"].Insert(0, thumb);
            de.CommitChanges();
            de.Close();
        }


        /// <summary>
        /// Vergleich des alten und neuen Fotos
        /// </summary>
        /// <returns>Gibt bei Erfolg - true - zurück</returns>
        private Boolean AreBitmapEqual(Bitmap pictureOne, Bitmap pictureTwo)
        {
            if (Bitmap.ReferenceEquals(pictureOne, pictureTwo)) return true;
            if (!pictureOne.Width.Equals(pictureTwo.Width)) return false;
            if (!pictureOne.Height.Equals(pictureTwo.Height)) return false;
            if (!pictureOne.PixelFormat.Equals(pictureTwo.PixelFormat)) return false;

            try
            {
                Byte[] imageBytesOne = new Byte[1];
                Byte[] imageBytesTwo = new Byte[1];

                imageBytesOne = (Byte[])converter.ConvertTo(pictureOne, imageBytesOne.GetType());
                imageBytesTwo = (Byte[])converter.ConvertTo(pictureTwo, imageBytesTwo.GetType());

                SHA256Managed sha = new SHA256Managed();
                Byte[] imageHashOne = sha.ComputeHash(imageBytesOne);
                Byte[] imageHashTwo = sha.ComputeHash(imageBytesTwo);

                for (int i = 0; i < imageHashOne.Length && i < imageHashTwo.Length; i++)
                {
                    if (!imageBytesOne[i].Equals(imageBytesTwo[i]))
                        return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                myLogger.FatalException("Vergleich fehlgeschlagen.", ex);
                return false;
            }
        }
    }
}

